/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package myxa;

import com.ibm.db2.jcc.DB2Xid;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sql.XAConnection;
import javax.sql.XADataSource;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;

/**
 *
 * @author Tuandn
 */
public class DistributedDataSource {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        XADataSource mssqlXaDS = null;
        XADataSource db2XaDS = null;

        XAConnection mssqlXaCon = null;
        XAConnection db2XaCon = null;

        XAResource mssqlXaRes = null;
        XAResource db2XaRes = null;

        Connection mssqlCon = null;
        Connection db2Con = null;

        Xid xid = null;

        Statement mssqlStmt = null;
        Statement db2Stmt = null;

        xid = new DB2Xid(100, new byte[]{0x44, 0x11, 0x55, 0x66}, new byte[]{0x00, 0x09, 0x00});
        xid = MyXid.getUniqueXid(1);
//            xid = new MyXid(100, new byte[]{0x00, 0x12, 0x00}, new byte[]{0x44, 0x11, 0x55, 0x66});
        int ret1;
        int ret2;
        try {
            //transaction branch for mssql
            Logger.getLogger(Main.class.getName()).log(Level.INFO, "get xa connection");

            mssqlXaDS = (XADataSource) DataSourceFactory.getMSSQLDataSource();
            db2XaDS = DataSourceFactory.getDB2DataSource();

            mssqlXaCon = mssqlXaDS.getXAConnection(DataSourceFactory.MSSQL_USERNAME, DataSourceFactory.MSSQL_PASSWORD);
            db2XaCon = db2XaDS.getXAConnection(DataSourceFactory.DB2_USERNAME, DataSourceFactory.DB2_PASSWORD);

            mssqlCon = mssqlXaCon.getConnection();
            db2Con = db2XaCon.getConnection();

            mssqlXaRes = mssqlXaCon.getXAResource();
            db2XaRes = db2XaCon.getXAResource();

            mssqlXaRes.start(xid, XAResource.TMNOFLAGS);
            db2XaRes.start(xid, XAResource.TMNOFLAGS);

            Logger.getLogger(Main.class.getName()).log(Level.INFO, "modify mssql data");
            mssqlStmt = mssqlCon.createStatement();
            mssqlStmt.executeUpdate("insert into tblLog(message, user_id) values ('short xmessage', 64)");
            /**
             * throw an exception
             */
//            mssqlStmt.executeUpdate("insert into tblLog(message, user_id) values ('an exception', 1)");
            Logger.getLogger(Main.class.getName()).log(Level.INFO, "modify db2 data");
            db2Stmt = db2Con.createStatement();
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss-");
            final String prefix = sdf.format(new Date(System.currentTimeMillis()));
//            db2Stmt.executeUpdate("insert into sqlj.customer (email) values ('" + prefix + "dntuan@yahoo.net')");
            /**
             * throw an exception
             */
            db2Stmt.executeUpdate("insert into sqlj.customer (email) values ('dntuan@yahoo.net')");
            mssqlXaRes.end(xid, XAResource.TMSUCCESS);
            db2XaRes.end(xid, XAResource.TMSUCCESS);

            ret1 = mssqlXaRes.prepare(xid);
            System.out.println("result 1: " + ret1);
            if (ret1 == XAResource.XA_OK) {
                ret2 = db2XaRes.prepare(xid);
                System.out.println("result 2: " + ret2);
                if (ret2 == XAResource.XA_OK) {
                    mssqlXaRes.commit(xid, false);
                    db2XaRes.commit(xid, false);
                }
            }

            Logger.getLogger(Main.class.getName()).log(Level.INFO, "modify successfully");
        } catch (XAException e) {
            e.printStackTrace();
            try {
                Logger.getLogger(Main.class.getName()).log(Level.INFO, "mssql: rollback");
                mssqlXaRes.rollback(xid);

                Logger.getLogger(Main.class.getName()).log(Level.INFO, "db2: rollback");
                db2XaRes.rollback(xid);
            } catch (XAException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, "xa exception", ex);
                ex.printStackTrace();
            }
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                Logger.getLogger(Main.class.getName()).log(Level.INFO, "mssql: rollback");
                mssqlXaRes.rollback(xid);
                Logger.getLogger(Main.class.getName()).log(Level.INFO, "db2: rollback");
                db2XaRes.rollback(xid);
            } catch (XAException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, "sql exception", ex);
            }
        } finally {
            try {
                mssqlCon.close();
                mssqlXaCon.close();
                db2Con.close();
                db2XaCon.close();
            } catch (SQLException ex) {
                Logger.getLogger(DistributedDataSource.class.getName()).log(Level.SEVERE, "finally", ex);
                ex.printStackTrace();
            }
        }
    }
}
